import { defineComponent, reactive, watch } from "vue";
import { ElButton, ElMessage } from "element-plus";

import useCopy from "@/hook/useCopy";
import { debounce } from "@/utils";

import Blocklayout from "@/components/layout/Blocklayout.vue";
import MonacoDditor from "@/components/Document/MonacoDditor/MonacoDditor.vue";
import CommonMenu from "@/components/CommonMenu.vue";

import cssModule from "./index.module.scss";
import menuConfig, { type MenuOptionType } from "./menuConfig";
import type { ColumnType, CrudOptionType } from "./type";

/** 状态类型 */
export type StateType = {
  /** 输入的文本 */
  json: string;
  /** 生成的类型文本 */
  genType: string;
  /** 菜单配置 */
  menuOption: MenuOptionType;
};

export default defineComponent({
  setup() {
    const state = reactive<StateType>({
      json: "",
      genType: "",
      menuOption: {
        dataStyle: "dicData",
        dicDataValueKey: "label",
        dicDataKeyKey: "value",
        splitSymbol: ",",
        isSingleQuotes: false,
        toNumber: false
      }
    });

    const generateType = debounce(() => {
      if (!state.json) {
        ElMessage.warning("不能为空");
        return;
      }

      try {
        // const json = JSON.parse(state.json);
        const json = eval(state.json);
        console.log("json: ", json);
        let genType = "";
        if (state.menuOption.dataStyle === "dicData") {
          genType = paraseDic2Type(json);
        } else if (state.menuOption.dataStyle === "split") {
          genType = paraseSplitText2Type(json);
        } else if (state.menuOption.dataStyle === "yty-ui") {
          genType = parseYtyJson2Type(json);
        }

        if (genType) {
          state.genType = genType;
        }
      } catch (err: unknown) {
        console.log("err: ", err);
        if (err instanceof Error) ElMessage.error(err.message);
      }
    }, 300);

    /** 将字典解析成字面量类型 */
    const paraseDic2Type = (
      dicData: any[],
      value = state.menuOption.dicDataValueKey,
      key = state.menuOption.dicDataKeyKey
    ) => {
      const type = dicData
        .map(e => {
          if (state.menuOption.toNumber) {
            return `${Number(e[key])}`;
          } else {
            return `"${e[key]}"`;
          }
        })
        .join(" | ");
      const comments = ["/**", " * 这个类型的描述"];
      dicData.forEach(e => {
        comments.push(` * - \`${e[key]}\`: ${e[value]}`);
      });
      comments.push(` */`);
      const result = `${comments.join("\n")}\ntype typeName = ${type};`;
      return state.menuOption.isSingleQuotes ? result.replace(/"/g, "'") : result;
    };

    /** 将分割文本解析成字面量类型 */
    const paraseSplitText2Type = (text: string, splitSymbol = state.menuOption.splitSymbol) => {
      const dicData = text.split(splitSymbol).map(e => {
        return {
          label: `${e}的label`,
          value: state.menuOption.toNumber ? Number(e) : e
        };
      });
      return paraseDic2Type(dicData, "label", "value");
    };

    /** 将 yty-ui 表格配置解析成类型 */
    const parseYtyJson2Type = (option: any) => {
      /** 字段直接是否换行 */
      const isFieldLineFeed = true;

      const opt: CrudOptionType = option;

      // 所有的 column
      const allColumn: ColumnType[] = [];
      const column = opt?.column || [];

      const group = opt?.group || [];
      const allGroup = group.flatMap(e => e.column);

      [...column, ...allGroup].forEach(e => {
        const isSome = allColumn.some(item => item.prop === e.prop);
        if (!isSome) allColumn.push(e);
      });

      // 生成的类型
      const genType: string[] = ["/**", " * type description", " */", "export type FormType = {"];

      allColumn.forEach(e => {
        isFieldLineFeed && genType.push("");
        if (e.dicData) {
          let dicData: any[] = [];
          if (typeof e.dicData === "function") {
            dicData = e.dicData();
          } else {
            dicData = e.dicData;
          }
          const labelKey = e.props?.label || "label";
          const valueKey = e.props?.value || "value";

          genType.push(`/**`);
          genType.push(` * ${e.label}`);
          dicData.forEach(item => {
            genType.push(` * - \`${item[valueKey]}\`: ${item[labelKey]}`);
          });
          genType.push(` */`);
          const str = dicData.map(item => `"${item[valueKey]}"`).join(" | ");
          genType.push(`${e.prop}: ${str};`);
        } else {
          genType.push(`/** ${e.label} */`);
          genType.push(`${e.prop}: ${e.type === "number" ? "number" : "string"};`);
        }
        isFieldLineFeed && genType.push("");
      });

      // 添加 tab
      for (let i = 0; i < genType.length; i++) {
        const item = genType[i];
        if ([0, 1, 2, 3].includes(i)) continue;
        genType[i] = "\t" + item;
      }

      genType.push("};");
      return genType.join("\n");
    };

    watch(() => [state.json, state.menuOption], generateType, { deep: true });

    /** 插槽内容 */
    const slotContents = {
      left: () => <MonacoDditor v-model={state.json} language="javascript" />,
      menu: () => (
        <div>
          <CommonMenu menuConfig={menuConfig} v-model={state.menuOption} />
          <div class={cssModule["btn-item"]}>
            <ElButton type="primary" size="small" disabled={!state.json} onClick={() => useCopy(state.genType)}>
              复制
              <i class="iconfont icon-fuzhi" />
            </ElButton>
          </div>
        </div>
      ),
      right: () => <MonacoDditor v-model={state.genType} language="typescript" />
    };

    return () => (
      <div class={cssModule.container}>
        <Blocklayout rightStyle={{ padding: "4px" }} v-slots={slotContents} />
      </div>
    );
  }
});
